package cn.sourcespro.shiro.security;

import cn.sourcespro.shiro.crudparams.vo.Vo;
import cn.sourcespro.shiro.util.JwtTokenUtil;
import cn.sourcespro.shiro.util.RespUtil;
import cn.sourcespro.shiro.util.SpringUtil;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.authz.RolesAuthorizationFilter;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.util.WebUtils;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Set;

/**
 * security
 *
 * @author zhanghaowei
 * @date 2018/7/13
 */
public class JwtRolesAuthorizationFilter extends RolesAuthorizationFilter{

    @Override
    public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws IOException {
        String[] rolesArray = (String[]) mappedValue;
        //如果没有角色限制，直接放行
        if (rolesArray == null || rolesArray.length == 0) {
            return true;
        }

        Set<String> roles = CollectionUtils.asSet(rolesArray);

        String token = WebUtils.toHttp(request).getHeader("token");
        DecodedJWT verifyToken = JwtTokenUtil.verifyToken(token);
        Claim claim = verifyToken.getClaim("roles");
        List<String> userRoles = claim.asList(String.class);

        for (String role : roles) {
            for (String userRole : userRoles) {
                if (role.equals(userRole)) {
                    return true;
                }
            }
        }

        return false;
    }

    @Override
    public boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
        HttpServletRequest servletRequest = (HttpServletRequest) request;
        HttpServletResponse servletResponse = (HttpServletResponse) response;
        //处理跨域问题，跨域的请求首先会发一个options类型的请求
        if (servletRequest.getMethod().equals(HttpMethod.OPTIONS.name())) {
            return true;
        }
        boolean isAccess = isAccessAllowed(request, response, mappedValue);
        if (isAccess) {
            return true;
        }

        String token = WebUtils.toHttp(request).getHeader("token");
        DecodedJWT verifyToken = JwtTokenUtil.verifyToken(token);
        List<String> audience = verifyToken.getAudience();
        if (CollectionUtils.isEmpty(audience)) {
            RespUtil.send(response, "您还未登录，请先登录", HttpStatus.FORBIDDEN);
        } else {
            RespUtil.send(response, "您没有此角色，请联系管理员", HttpStatus.FORBIDDEN);
        }

        return false;

    }
}
